注意,这里说的提权不是从Administrator
提升到 System
,只是开启一些Administrator
组的特殊权限
查看用户组信息使用命令 whoami /all
Administrator组
管理员组一般权限比较多,但是很多都禁用了,我们这里需要的是SeDebugPrivilege
,要是进程拥有了这个权限,就能对任意进程进行操作(包括system
)
当用户试图执行一个特权操作,系统检查用户的访问令牌以确定使用是否具有必要的特权。调用GetTokenInformation函数可以检查特权。
我要做的就是找到找到一个系统中有SeDebugPrivilege
权限的令牌,然后复制下来,把自己的令牌改为他这个,然乎自己就拥有了SeDebugPrivilege
权限了。这也就是提升权限的核心。
下图是我使用 OpenProcess
对SID为4的系统进程进行操作,且操作权限是PROCESS_ALL_ACCESS
下面看看具体实现
void CgPivilige()
{
BOOL retn;
HANDLE hToken;
retn = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | READ_CONTROL, &hToken);//修改令牌特权值
if (retn != TRUE)
{
printf("获取令牌句柄失败!" );
return;
}
TOKEN_PRIVILEGES tp; //新特权结构体
LUID Luid;
retn = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid);//查看具有调试权限的令牌
if (retn != TRUE)
{
printf("获取Luid失败" );
return;
}
//给TP和TP里的LUID结构体赋值
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = Luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);//调整自己Token为有调试特权的Token
if (GetLastError() != ERROR_SUCCESS)
{
printf("修改特权不完全或失败!" );
}
else
{
printf("修改成功!" );
}
}
下面给一个病毒使用的提升权限 IDA伪代码
int __cdecl reloadToken_4108F0(LPCWSTR lpName)
{
HANDLE v2; // eax
struct _LUID Luid; // [esp+0h] [ebp-24h]
HANDLE TokenHandle; // [esp+8h] [ebp-1Ch]
struct _TOKEN_PRIVILEGES NewState; // [esp+Ch] [ebp-18h]
if ( !LookupPrivilegeValueW(0, lpName, &Luid) )// lpnmae SedebugPrivilege 查看拥有调试权限的令牌
return 0;
v2 = GetCurrentProcess();
if ( !OpenProcessToken(v2, 0x20028u, &TokenHandle) )// 0x20028 = TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY|READ_CONTROL
return 0;
NewState.Privileges[0].Luid = Luid;
NewState.PrivilegeCount = 1;
NewState.Privileges[0].Attributes = 2;
AdjustTokenPrivileges(TokenHandle, 0, &NewState, 0, 0, 0);// 将访问令牌中禁用的权限启用,来达到权限提升
CloseHandle(TokenHandle);
return 1;
}
普通用户组
普通用户组本身权限就比较少
Crat是普通用户组成员
普通用户一般是没有SeDebugPrivilege
权限的,也就是说这个用户组根本就没这个权限,不是能不能打开的问题,而是根本没有。
所以普通用户不存在什么使用令牌的权限提升,即使有,都只是很小的一些权限。
查看进程权限
程序能运行在low
medium
hight
三个level下,那怎么在通过代码检测自己拥有什么权限呢?
通过GetTokenInformation
拿到这个进程的TokenInformation
信息 再通过比较Label.Sid,
的值
void ShowProcessIntegrityLevel()
{
HANDLE hToken;
HANDLE hProcess;
DWORD dwLengthNeeded;
DWORD dwError = ERROR_SUCCESS;
PTOKEN_MANDATORY_LABEL pTIL = NULL;
DWORD dwIntegrityLevel;
hProcess = GetCurrentProcess();
if (OpenProcessToken(hProcess, TOKEN_QUERY |
TOKEN_QUERY_SOURCE, &hToken))
{
// Get the Integrity level.
if (!GetTokenInformation(hToken, TokenIntegrityLevel,
NULL, 0, &dwLengthNeeded))
{
dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0,
dwLengthNeeded);
if (pTIL != NULL)
{
if (GetTokenInformation(hToken, TokenIntegrityLevel,
pTIL, dwLengthNeeded, &dwLengthNeeded))
{
dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid,
(DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
if (dwIntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID)
{
// Low Integrity
wprintf(L"Low Integrity Process");
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
{
// Medium Integrity
wprintf(L"Medium Integrity Process");
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
{
// High Integrity
wprintf(L"High Integrity Process");
}
}
LocalFree(pTIL);
}
}
}
CloseHandle(hToken);
}
}
参考 https://www.cnblogs.chom/hqu-ye/articles/4838381.html